﻿using CoreDomain;
using DomainService.IService;
using Infrastructure;
using Infrastructure.IRepository;
using Infrastructure.Repository;
using Model.BusinessModel;
using Model.BusinessModel.InPut;
using Model.BusinessModel.OutPut;
using Model.DomainModel;
using Model.Flow;
using Model.OverallAtuhModel;
using System.Linq;
using Utility;
using Utility.Enum;

namespace DomainService.Service
{
    /// <summary>
    /// 流程申请服务接口实现
    /// </summary>
    public class FlowApplyService : IFlowApplyService
    {
        #region 构造实列化

        //仓储接口
        private readonly IFlowApplyRepository _flowApplyRepository;
        private readonly IFlowRepository _flowRepository;
        private readonly IFlowApplyRecordRepository _flowApplyRecordRepository;
        private readonly IFlowMessageRepository _flowMessageRepository;
        /// <summary>
        /// 基础服务
        /// </summary>
        private readonly IBaseService _baseService;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="FlowApplyRepository"></param>
        /// <param name="flowRepository"></param>
        /// <param name="FlowApplyRecordRepository"></param>
        /// <param name="baseService"></param>
        public FlowApplyService(IFlowApplyRepository flowApplyRepository, IFlowRepository flowRepository,
             IFlowApplyRecordRepository flowApplyRecordRepository, IBaseService baseService, IFlowMessageRepository flowMessageRepository)
        {
            _flowApplyRepository = flowApplyRepository;
            _flowRepository = flowRepository;
            _flowApplyRecordRepository = flowApplyRecordRepository;
            _baseService = baseService;
            _flowMessageRepository = flowMessageRepository;
        }

        #endregion

        #region 接口实现

        /// <summary>
        /// 新增流程申请信息
        /// </summary>
        /// <param name="FlowApply">实体模型</param>
        /// <returns></returns>
        public ReceiveStatus Insert(FlowApply FlowApply)
        {
            ReceiveStatus receiveStatus = new();

            //新增前验证
            var flowModel = _flowRepository.GetByKey(FlowApply.FlowId, BaseSqlRepository.flow_selectByKeySql);
            if (flowModel == null)
                return ExceptionHelper.CustomException("流程信息不存在，新增失败！");

            var flowApplyModel = _flowApplyRepository.GetFlowApplyByApplyTitle(FlowApply.ApplyTitle);
            if (flowApplyModel != null)
                return ExceptionHelper.CustomException(string.Format("申请标题【{0}】重复，请重新填写!", FlowApply.ApplyTitle));

            FlowApply.FormId = flowModel.FormId;
            FlowApply.FlowContent = flowModel.FlowContent;
            FlowApply.IsPublish = true;
            //FlowApply.FlowApplyState = FlowApply.FlowApplyState;

            //流程验证
            var flowData = JsonHelper.JsonStrToEntity<FlowModel>(flowModel.FlowContent);
            var data = FlowCore.VerifyFlow(flowData);
            if (!data.Item2)
                return ExceptionHelper.CustomException(data.Item1);

            //获取流程开始节点
            var startNode = FlowCore.GetStartNode(flowData);

            //当前节点信息
            var currentFlowModel = FlowCore.StartFlow(flowData, FlowApply.FormData);
            if (currentFlowModel == null || currentFlowModel.data == null)
                return ExceptionHelper.CustomException("不存在下一个节点，新增失败！");

            //设置当前节点和下个节点审核信息
            var loginResult = _baseService.GetUserInfo();
            SetNodeData(currentFlowModel.id, flowData, FlowApply, false, loginResult);
            //是否发布
            if (FlowApply.IsPublish == true)
            {
                FlowApply.FlowApplyState = (int)FlowApplyStateEnum.InExamine;
                FlowApply.CurrentNodeState = (int)FlowNodeStateEnum.InExamine;
                flowData = FlowCore.SetEdgesAnimated(flowData, startNode.id, currentFlowModel.id, true, EdgesClassStyleEnum.inExamineEdgesColor);
                FlowApply.FlowContent = JsonHelper.SerializeObjToJson(flowData);
            }
            else
            {
                FlowApply.FlowApplyState = (int)FlowApplyStateEnum.UnPublish;
                FlowApply.CurrentNodeState = (int)FlowNodeStateEnum.UnPublish;
            }

            FlowApply.FormId = flowModel.FormId;
            FlowApply.FlowContent = JsonHelper.SerializeObjToJson(FlowCore.SetCurrentNodeClass(flowData, currentFlowModel.id, NodeClassStyleEnum.inExamineBackColor));
            FlowApply.FlowApplyId = Guid.NewGuid().ToString();
            FlowApply.DataState = DataStateEnum.Enable;

            //组织审核记录数据
            FlowApplyRecord FlowApplyRecord = new()
            {
                FlowApplyRecordId = Guid.NewGuid().ToString(),
                FlowApplyId = FlowApply.FlowApplyId,
                NodeId = startNode.id,
                NodeName = startNode.data.label,
                NodeType = startNode.type,
                NodeReviewerId = loginResult.UserId.ToString(),
                NodeReviewerName = loginResult.UserName,
                NodeExamineState = (int)FlowNodeStateEnum.AuditPass,
                CreateTime = DateTime.Now,
                CreateUserKey = loginResult.UserId.ToString(),
                ExamineRemark = string.Empty,
            };

            //写入数据库
            TransactionHelper.ExecuteTransaction(() =>
            {
                _flowApplyRepository.Insert(FlowApply, BaseSqlRepository.flowApply_insertSql);
                if (!string.IsNullOrWhiteSpace(FlowApplyRecord.FlowApplyRecordId) && FlowApply.IsPublish == true)
                    _flowApplyRecordRepository.Insert(FlowApplyRecord, BaseSqlRepository.flowApplyRecord_insertSql);
            });
            return receiveStatus;
        }

        /// <summary>
        /// 更新流程申请信息
        /// </summary>
        /// <param name="FlowApply">实体模型</param>
        /// <param name="loginResult">登陆人员信息</param>
        /// <returns></returns>
        public ReceiveStatus Update(FlowApply FlowApply)
        {
            ReceiveStatus receiveStatus = new();
            var model = _flowApplyRepository.GetByKey(FlowApply.FlowApplyId, BaseSqlRepository.flowApply_selectByKeySql);
            if (model == null)
                return ExceptionHelper.CustomException("该申请不存在，更新失败！");

            //新增前验证
            var flowModel = _flowRepository.GetByKey(FlowApply.FlowId, BaseSqlRepository.flow_selectByKeySql);
            if (flowModel == null)
                return ExceptionHelper.CustomException("流程信息不存在，更新失败！");

            var flowApplyModel = _flowApplyRepository.GetFlowApplyByApplyTitle(FlowApply.ApplyTitle);
            if (flowApplyModel != null && FlowApply.FlowApplyId != flowApplyModel.FlowApplyId)
                return ExceptionHelper.CustomException(string.Format("申请标题【{0}】重复，请重新填写!", FlowApply.ApplyTitle));

            //流程验证
            var flowData = JsonHelper.JsonStrToEntity<FlowModel>(flowModel.FlowContent);
            var data = FlowCore.VerifyFlow(flowData);
            if (!data.Item2)
                return ExceptionHelper.CustomException(data.Item1);

            //获取流程开始节点
            var startNode = FlowCore.GetStartNode(flowData);

            //当前节点信息
            var currentFlowModel = FlowCore.StartFlow(flowData, FlowApply.FormData);
            if (currentFlowModel == null || currentFlowModel.data == null)
                return ExceptionHelper.CustomException("不存在下一个节点，更新失败！");

            //设置当前节点和下个节点审核信息
            var loginResult = _baseService.GetUserInfo();
            SetNodeData(currentFlowModel.id, flowData, FlowApply, false, loginResult);

            //是否发布
            if (FlowApply.IsPublish == true)
            {
                FlowApply.FlowApplyState = (int)FlowApplyStateEnum.InExamine;
                FlowApply.CurrentNodeState = (int)FlowNodeStateEnum.InExamine;
                flowData = FlowCore.SetEdgesAnimated(flowData, startNode.id, currentFlowModel.id, true, EdgesClassStyleEnum.inExamineEdgesColor);
                FlowApply.FlowContent = JsonHelper.SerializeObjToJson(flowData);
            }
            else
            {
                FlowApply.FlowApplyState = (int)FlowApplyStateEnum.UnPublish;
                FlowApply.CurrentNodeState = (int)FlowNodeStateEnum.UnPublish;
            }

            FlowApply.FormId = flowModel.FormId;
            FlowApply.FlowContent = JsonHelper.SerializeObjToJson(FlowCore.SetCurrentNodeClass(flowData, currentFlowModel.id, NodeClassStyleEnum.inExamineBackColor));
            FlowApply.CreateTime = model?.CreateTime ?? FlowApply.CreateTime;
            FlowApply.CreateUserKey = model?.CreateUserKey ?? FlowApply.CreateUserKey;

            //验证最新一条开始节点记录是否为审核通过
            FlowApplyRecord FlowApplyRecord = new();
            var flowApplyRecordModel = _flowApplyRecordRepository.GetFlowApplyRecordByNodeId(startNode.id, FlowApply.FlowApplyId).FirstOrDefault();
            if (flowApplyRecordModel != null && flowApplyRecordModel.NodeExamineState != (int)FlowNodeStateEnum.AuditPass)
            {
                //组织审核记录
                FlowApplyRecord = new()
                {
                    FlowApplyRecordId = Guid.NewGuid().ToString(),
                    FlowApplyId = FlowApply.FlowApplyId,
                    NodeId = startNode.id,
                    NodeName = startNode.data.label,
                    NodeType = startNode.type,
                    NodeReviewerId = loginResult.UserId.ToString(),
                    NodeReviewerName = loginResult.UserName,
                    NodeExamineState = (int)FlowNodeStateEnum.AuditPass,
                    CreateTime = DateTime.Now,
                    CreateUserKey = loginResult.UserId.ToString(),
                    ExamineRemark = string.Empty,
                };
            }

            //写入数据库
            TransactionHelper.ExecuteTransaction(() =>
            {
                _flowApplyRepository.Update(FlowApply, BaseSqlRepository.flowApply_updateSql);
                if (!string.IsNullOrWhiteSpace(FlowApplyRecord.FlowApplyRecordId) && FlowApply.IsPublish == true)
                    _flowApplyRecordRepository.Insert(FlowApplyRecord, BaseSqlRepository.flowApplyRecord_insertSql);
            });
            return receiveStatus;
        }

        /// <summary>
        /// 获取所有流程申请
        /// </summary>
        /// <param name="pageResultModel">分页模型</param>
        /// <returns></returns>
        public PageResultModel<FlowApplyOutPut> GetAllFlowApply(FlowApplyInput pageResultModel)
        {
            pageResultModel.tableField = " FlowApplyId,ApplyTitle,IsPublish,FlowApplyState,UrgentIndex,CurrentNodeId,CurrentNodeName,CurrentNodeReviewerName,CurrentNodeState,NextNodeName,NextNodeReviewerName,a.Remark,a.CreateTime,b.FlowName,c.FormName,a.CreateUserKey,a.DataState  ";
            pageResultModel.tableName = @" FlowApply as a
                                            inner join Flow as b on a.FlowId = b.FlowId
                                            inner join Form as c on a.FormId = c.FormId  ";
            pageResultModel.orderByField = " a.CreateTime ";
            pageResultModel.sortType = " desc ";

            //查询条件
            var loginResult = _baseService.GetUserInfo();
            var queryWhere = string.Empty;
            if (!string.IsNullOrWhiteSpace(loginResult?.UserId ?? string.Empty))
                queryWhere = $"{queryWhere} and a.CreateUserKey =  '{loginResult.UserId}'";
            if (!string.IsNullOrWhiteSpace(pageResultModel.ApplyTitle))
                queryWhere = $"{queryWhere} and a.ApplyTitle like '%{pageResultModel.ApplyTitle}%'";
            if (!string.IsNullOrWhiteSpace(pageResultModel.FlowApplyState))
                queryWhere = $"{queryWhere} and a.FlowApplyState= {pageResultModel.FlowApplyState}";

            if (pageResultModel.CreateTimeStart != null)
                queryWhere = $"{queryWhere} and a.CreateTime>='{pageResultModel.CreateTimeStart}'";
            if (pageResultModel.CreateTimeEnd != null)
                queryWhere = $"{queryWhere} and a.CreateTime<'{pageResultModel.CreateTimeEnd.Value.AddDays(1)}'";

            //数据权限
            var menuId = _baseService.GetCurrentMenuId();
            var authWhere = _flowApplyRepository.GetDataAuthWhere(menuId, "a", RuleTypeEnum.DataRowRule);
            pageResultModel.selectWhere = $"{queryWhere}{authWhere}";

            var list = _flowApplyRepository.GetPageList<FlowApplyOutPut>(pageResultModel);

            var userList = MemoryCacheHelper.GetCachedDataByKey<List<SysUser>>(ConstHelper.UserCacheKey);
            var depList = MemoryCacheHelper.GetCachedDataByKey<List<SysDepartment>>(ConstHelper.DepartmentCacheKey);
            foreach (var item in list.data)
            {
                item.FlowApplyStateName = EnumHelper.GetDescription((FlowApplyStateEnum)item.FlowApplyState);
                item.CreateUserName = userList.data?.Find(f => f.UserId == item.CreateUserKey)?.UserName ?? string.Empty;
            }
            //list.data.AppendUserData();

            return list;
        }


        /// <summary>
        /// 获取等待审批流程
        /// </summary>
        /// <param name="pageResultModel">分页模型</param>
        /// <returns></returns>
        public PageResultModel<WaitApprovalFlowOutPut> GetWaitApprovalFlow(FlowApplyInput pageResultModel)
        {
            pageResultModel.tableField = " FlowApplyId,ApplyTitle,IsPublish,FlowApplyState,UrgentIndex,CurrentNodeId,CurrentNodeName,CurrentNodeReviewerName,CurrentNodeState,NextNodeName,NextNodeReviewerName,a.Remark,a.CreateTime,b.FlowName,c.FormName,a.CreateUserKey,a.DataState  ";
            pageResultModel.tableName = @" FlowApply as a
                                            inner join Flow as b on a.FlowId = b.FlowId
                                            inner join Form as c on a.FormId = c.FormId  ";
            pageResultModel.orderByField = " a.CreateTime ";
            pageResultModel.sortType = " desc ";

            //查询条件
            var loginResult = _baseService.GetUserInfo();
            var queryWhere = string.Format(" and FlowApplyState |{0}={0} ", (int)FlowApplyStateEnum.InExamine + (int)FlowApplyStateEnum.AuditDismissal);
            if (!string.IsNullOrWhiteSpace(loginResult?.UserId ?? string.Empty))
                queryWhere = $"{queryWhere} and a.CurrentNodeReviewerId like '%{loginResult.UserId}%'";
            if (!string.IsNullOrWhiteSpace(pageResultModel.ApplyTitle))
                queryWhere = $"{queryWhere} and a.ApplyTitle like '%{pageResultModel.ApplyTitle}%'";
            if (!string.IsNullOrWhiteSpace(pageResultModel.FlowApplyState))
                queryWhere = $"{queryWhere} and a.FlowApplyState= {pageResultModel.FlowApplyState}";
            if (pageResultModel.CreateTimeStart != null)
                queryWhere = $"{queryWhere} and a.CreateTime>='{pageResultModel.CreateTimeStart}'";
            if (pageResultModel.CreateTimeEnd != null)
                queryWhere = $"{queryWhere} and a.CreateTime<'{pageResultModel.CreateTimeEnd.Value.AddDays(1)}'";

            //数据权限
            var menuId = _baseService.GetCurrentMenuId();
            var authWhere = _flowApplyRepository.GetDataAuthWhere(menuId, "a", RuleTypeEnum.DataRowRule);
            pageResultModel.selectWhere = $"{queryWhere}{authWhere}";

            var list = _flowApplyRepository.GetPageList<WaitApprovalFlowOutPut>(pageResultModel);

            var userList = MemoryCacheHelper.GetCachedDataByKey<List<SysUser>>(ConstHelper.UserCacheKey);
            var depList = MemoryCacheHelper.GetCachedDataByKey<List<SysDepartment>>(ConstHelper.DepartmentCacheKey);
            foreach (var item in list.data)
            {
                item.FlowApplyStateName = EnumHelper.GetDescription((FlowApplyStateEnum)item.FlowApplyState);
                item.CreateUserName = userList.data?.Find(f => f.UserId == item.CreateUserKey)?.UserName ?? string.Empty;
            }

            return list;
        }

        /// <summary>
        /// 获取已审核审批流程
        /// </summary>
        /// <param name="pageResultModel">分页模型</param>
        /// <returns></returns>
        public PageResultModel<AuditedApprovalFlowOutPut> GetAuditedApprovalFlow(FlowApplyInput pageResultModel)
        {
            pageResultModel.tableField = "  a.FlowApplyId,ApplyTitle,IsPublish,FlowApplyState,UrgentIndex,CurrentNodeId,CurrentNodeName,CurrentNodeReviewerName,CurrentNodeState,NextNodeName,NextNodeReviewerName,a.Remark,a.CreateTime,b.FlowName,c.FormName,a.CreateUserKey,a.DataState   ";
            pageResultModel.tableName = @" FlowApply as a
                                            inner join Flow as b on a.FlowId = b.FlowId
                                            inner join Form as c on a.FormId = c.FormId 
                                            inner join FlowApplyRecord as d on d.FlowApplyId = a.FlowApplyId";
            pageResultModel.groupByField = "   a.FlowApplyId,ApplyTitle,IsPublish,FlowApplyState,UrgentIndex,CurrentNodeId,CurrentNodeName,CurrentNodeReviewerName,CurrentNodeState,NextNodeName,NextNodeReviewerName,a.Remark,a.CreateTime,b.FlowName,c.FormName,a.CreateUserKey,a.DataState  ";
            pageResultModel.orderByField = " a.CreateTime ";
            pageResultModel.sortType = " desc ";

            //查询条件
            var loginResult = _baseService.GetUserInfo();
            var queryWhere = string.Empty;
            if (!string.IsNullOrWhiteSpace(loginResult?.UserId ?? string.Empty))
                queryWhere = $"{queryWhere} and d.NodeReviewerId =  '{loginResult.UserId}'";
            if (!string.IsNullOrWhiteSpace(pageResultModel.ApplyTitle))
                queryWhere = $"{queryWhere} and a.ApplyTitle like '%{pageResultModel.ApplyTitle}%'";
            if (!string.IsNullOrWhiteSpace(pageResultModel.FlowApplyState))
                queryWhere = $"{queryWhere} and a.FlowApplyState= {pageResultModel.FlowApplyState}";
            if (pageResultModel.CreateTimeStart != null)
                queryWhere = $"{queryWhere} and a.CreateTime>='{pageResultModel.CreateTimeStart}'";
            if (pageResultModel.CreateTimeEnd != null)
                queryWhere = $"{queryWhere} and a.CreateTime<'{pageResultModel.CreateTimeEnd.Value.AddDays(1)}'";

            //数据权限
            var queryWehre = string.Format(" and FlowApplyState |{0}={0} ", (int)FlowApplyStateEnum.AuditPass + (int)FlowApplyStateEnum.Cancel + (int)FlowApplyStateEnum.Filing);
            var menuId = _baseService.GetCurrentMenuId();
            var authWhere = _flowApplyRepository.GetDataAuthWhere(menuId, "a", RuleTypeEnum.DataRowRule);
            pageResultModel.selectWhere = $"{queryWhere}{authWhere}";

            var list = _flowApplyRepository.GetPageList<AuditedApprovalFlowOutPut>(pageResultModel);

            var userList = MemoryCacheHelper.GetCachedDataByKey<List<SysUser>>(ConstHelper.UserCacheKey);
            var depList = MemoryCacheHelper.GetCachedDataByKey<List<SysDepartment>>(ConstHelper.DepartmentCacheKey);
            foreach (var item in list.data)
            {
                item.FlowApplyStateName = EnumHelper.GetDescription((FlowApplyStateEnum)item.FlowApplyState);
                item.CreateUserName = userList.data?.Find(f => f.UserId == item.CreateUserKey)?.UserName ?? string.Empty;
            }

            return list;
        }

        /// <summary>
        /// 获取抄送流程
        /// </summary>
        /// <param name="pageResultModel">分页模型</param>
        /// <returns></returns>
        public PageResultModel<CarbonCopyFlowOutPut> GetCarbonCopyFlow(FlowApplyInput pageResultModel)
        {
            pageResultModel.tableField = " a.FlowApplyId,ApplyTitle,IsPublish,FlowApplyState,UrgentIndex,CurrentNodeId,CurrentNodeName,CurrentNodeReviewerName,CurrentNodeState,NextNodeName,NextNodeReviewerName,a.Remark,a.CreateTime,b.FlowName,c.FormName,a.CreateUserKey,a.DataState,d.MessageRecipient,d.MessageSender  ";
            pageResultModel.tableName = @" FlowApply as a
                                            inner join Flow as b on a.FlowId = b.FlowId
                                            inner join Form as c on a.FormId = c.FormId
                                            inner join FlowMessage d on a.FlowApplyId = d.FlowApplyId  ";
            pageResultModel.orderByField = " d.CreateTime ";
            pageResultModel.sortType = " desc ";

            //查询条件
            var loginResult = _baseService.GetUserInfo();
            var queryWhere = string.Format(" and d.MessageType ={0} ", (int)MessageTypeEnum.CarbonCopy);
            if (!string.IsNullOrWhiteSpace(loginResult?.UserId ?? string.Empty))
                queryWhere = $"{queryWhere} and d.MessageRecipient='{loginResult.UserId}'";
            if (!string.IsNullOrWhiteSpace(pageResultModel.ApplyTitle))
                queryWhere = $"{queryWhere} and a.ApplyTitle like '%{pageResultModel.ApplyTitle}%'";
            if (!string.IsNullOrWhiteSpace(pageResultModel.FlowApplyState))
                queryWhere = $"{queryWhere} and a.FlowApplyState= {pageResultModel.FlowApplyState}";
            if (pageResultModel.CreateTimeStart != null)
                queryWhere = $"{queryWhere} and a.CreateTime>='{pageResultModel.CreateTimeStart}'";
            if (pageResultModel.CreateTimeEnd != null)
                queryWhere = $"{queryWhere} and a.CreateTime<'{pageResultModel.CreateTimeEnd.Value.AddDays(1)}'";

            //数据权限
            var menuId = _baseService.GetCurrentMenuId();
            var authWhere = _flowApplyRepository.GetDataAuthWhere(menuId, "a", RuleTypeEnum.DataRowRule);
            pageResultModel.selectWhere = $"{queryWhere}{authWhere}";

            var list = _flowApplyRepository.GetPageList<CarbonCopyFlowOutPut>(pageResultModel);

            var userList = MemoryCacheHelper.GetCachedDataByKey<List<SysUser>>(ConstHelper.UserCacheKey);
            var depList = MemoryCacheHelper.GetCachedDataByKey<List<SysDepartment>>(ConstHelper.DepartmentCacheKey);
            foreach (var item in list.data)
            {
                item.FlowApplyStateName = EnumHelper.GetDescription((FlowApplyStateEnum)item.FlowApplyState);
                item.CreateUserName = userList.data?.Find(f => f.UserId == item.CreateUserKey)?.UserName ?? string.Empty;
                item.MessageRecipientName = userList.data?.Find(f => f.UserId == item.MessageRecipient)?.UserName ?? string.Empty;
                item.MessageSenderName = userList.data?.Find(f => f.UserId == item.MessageSender)?.UserName ?? string.Empty;
            }

            return list;
        }

        /// <summary>
        /// 根据申请id获取数据
        /// </summary>
        /// <param name="flowApplyId">主键</param>
        /// <returns></returns>
        public ReceiveStatus<FlowApplyExtendOutPut> GetFlowApplyByApplyId(string flowApplyId)
        {
            ReceiveStatus<FlowApplyExtendOutPut> receiveStatus = new();
            var flowApplyModel = _flowApplyRepository.GetFlowApplyByApplyId(flowApplyId);
            if (flowApplyModel == null)
                return ExceptionHelper<FlowApplyExtendOutPut>.CustomExceptionData("申请不存在或已删除！");
            receiveStatus.data = flowApplyModel;
            return receiveStatus;
        }

        /// <summary>
        /// 更新发布状态
        /// </summary>
        /// <param name="flowApplyId">主键</param>
        /// <param name="isPublish">发布状态</param>
        /// <param name="loginResult">登录人员</param>
        /// <returns></returns>
        public ReceiveStatus UpdateIsPublish(string flowApplyId, bool isPublish)
        {
            ReceiveStatus receiveStatus = new();

            //更新状态前验证
            var flowApplyModel = _flowApplyRepository.GetByKey(flowApplyId, BaseSqlRepository.flowApply_selectByKeySql);
            if (flowApplyModel == null)
                return ExceptionHelper.CustomException("申请不存在或已删除！");
            var flowData = JsonHelper.JsonStrToEntity<FlowModel>(flowApplyModel.FlowContent);

            //获取流程开始节点
            var startNode = FlowCore.GetStartNode(flowData);
            //设置线条是否流动
            flowApplyModel.FlowContent = JsonHelper.SerializeObjToJson(FlowCore.SetEdgesAnimated(flowData, startNode.id, flowApplyModel.CurrentNodeId, true, EdgesClassStyleEnum.inExamineEdgesColor));
            flowApplyModel.IsPublish = isPublish;
            flowApplyModel.CurrentNodeState = (int)FlowNodeStateEnum.InExamine;
            flowApplyModel.FlowApplyState = (int)FlowApplyStateEnum.InExamine;

            var loginResult = _baseService.GetUserInfo();
            //组织审核记录数据
            FlowApplyRecord FlowApplyRecord = new()
            {
                FlowApplyRecordId = Guid.NewGuid().ToString(),
                FlowApplyId = flowApplyId,
                NodeId = startNode.id,
                NodeName = startNode.data.label,
                NodeType = startNode.type,
                NodeReviewerId = loginResult.UserId.ToString(),
                NodeReviewerName = loginResult.UserName,
                NodeExamineState = (int)FlowNodeStateEnum.AuditPass,
                CreateTime = DateTime.Now,
                CreateUserKey = loginResult.UserId.ToString(),
                ExamineRemark = string.Empty,
            };

            //写入数据库
            TransactionHelper.ExecuteTransaction(() =>
            {
                var count = _flowApplyRepository.Update(flowApplyModel, BaseSqlRepository.flowApply_updateSql);
                if (!string.IsNullOrWhiteSpace(FlowApplyRecord.FlowApplyRecordId) && isPublish == true)
                    _flowApplyRecordRepository.Insert(FlowApplyRecord, BaseSqlRepository.flowApplyRecord_insertSql);
                if (count == 0)
                {
                    receiveStatus.code = CodeStatuEnum.Error;
                    receiveStatus.msg = "更新失败";
                    receiveStatus.success = false;
                }
            });

            return receiveStatus;
        }

        /// <summary>
        /// 更新流程状态
        /// </summary>
        /// <param name="flowApplyId">流程id</param>
        /// <param name="flowApplyState">流程状态</param>
        /// <returns></returns>
        public ReceiveStatus UpdateFlowApplyState(string flowApplyId, int flowApplyState)
        {
            ReceiveStatus receiveStatus = new();
            if (string.IsNullOrWhiteSpace(flowApplyId))
                return ExceptionHelper.CustomException("请选择需要作废的申请！");
            var list = flowApplyId.Split(",").ToList();
            foreach (var item in list)
            {
                var applyModel = _flowApplyRepository.GetByKey(item, BaseSqlRepository.flowApply_selectByKeySql);
                if (applyModel.FlowApplyState == (int)FlowApplyStateEnum.AuditPass || applyModel.FlowApplyState == (int)FlowApplyStateEnum.Filing)
                    return ExceptionHelper.CustomException("审核完成和归档的申请不能作废！");
            }
            //写入数据库
            TransactionHelper.ExecuteTransaction(() =>
            {
                foreach (var item in list)
                {
                    _flowApplyRepository.UpdateFlowApplyState(item, flowApplyState);
                }
            });

            return receiveStatus;
        }

        /// <summary>
        /// 流程申请审核
        /// </summary>
        /// <param name="flowApplyExamineInput">审核信息</param>
        /// <param name="loginResult">登陆人员信息</param>
        /// <returns></returns>
        public ReceiveStatus FlowApplyExamine(FlowApplyExamineInput flowApplyExamineInput, LoginOutPut loginResult)
        {
            //当前节点审核状态
            var currentNodeState = (int)FlowNodeStateEnum.InExamine;
            ReceiveStatus receiveStatus = new();
            //验证申请是否存在
            var model = _flowApplyRepository.GetByKey(flowApplyExamineInput.FlowApplyId, BaseSqlRepository.flowApply_selectByKeySql);
            if (model == null)
                return ExceptionHelper.CustomException("该申请不存在，审核失败！");

            //验证是否为空
            if (string.IsNullOrEmpty(flowApplyExamineInput.ExamineNodeId))
                return ExceptionHelper.CustomException("审核节点不能为空，审核失败！");

            //验证是否是开始节点和归档节点
            var flowData = JsonHelper.JsonStrToEntity<FlowModel>(model.FlowContent);
            if (FlowCore.VerifyStartNode(flowData, flowApplyExamineInput.ExamineNodeId))
                return ExceptionHelper.CustomException("该节点为开始节点，审核失败！");

            //验证当前审核节点是否存在
            var examineNodeModel = FlowCore.GetCurrentNodeData(flowData, flowApplyExamineInput.ExamineNodeId);
            if (examineNodeModel == null)
                return ExceptionHelper.CustomException("该节点不存在，审核失败！");

            //验证当前节点是否审核--取最新一条
            var flowApplyRecordModel = _flowApplyRecordRepository.GetFlowApplyRecordByNodeId(flowApplyExamineInput.ExamineNodeId, flowApplyExamineInput.FlowApplyId).FirstOrDefault();
            if (flowApplyRecordModel != null && flowApplyRecordModel.NodeExamineState != (int)FlowNodeStateEnum.AuditDismissal)
            {
                if (flowApplyRecordModel.NodeExamineState != (int)FlowNodeStateEnum.InExamine && examineNodeModel.@class == NodeClassStyleEnum.agreeBackColor.ToString())
                    return ExceptionHelper.CustomException("该节点已审核！");
            }
            //获取上一个节点信息
            var previousNodelModel = FlowCore.GetPreviousFlowNodeMsg(flowData, flowApplyExamineInput.ExamineNodeId, model.FormData);
            if (previousNodelModel == null)
                return ExceptionHelper.CustomException("当前节点的上个节点不存在，审核失败！");

            //当前节点审核人集合
            var currentNodeReviewerIdList = model.CurrentNodeReviewerId.Split(",").ToList();
            if (string.IsNullOrWhiteSpace(loginResult.UserId))
                return ExceptionHelper.CustomException("登录失效，请重新登录");
            //驳回几点集合
            List<string> rejectNodeIdList = new List<string>();
            //同意
            if (flowApplyExamineInput.ExamineState == (int)FlowNodeStateEnum.AuditPass)
            {
                model.FlowApplyState = (int)FlowApplyStateEnum.InExamine;
                if (!currentNodeReviewerIdList.Contains(loginResult.UserId.ToString()))
                    return ExceptionHelper.CustomException("操作人员不是当前节点审批人员！");
                //设置节点数据
                currentNodeState = SetNodeData(flowApplyExamineInput.ExamineNodeId, flowData, model, true, loginResult);

                var edgesClassStyle = EdgesClassStyleEnum.agreeEdgesColor;
                var nodeClassStyle = NodeClassStyleEnum.agreeBackColor;
                if (currentNodeState == (int)FlowNodeStateEnum.InExamine)
                {
                    nodeClassStyle = NodeClassStyleEnum.inExamineBackColor;
                    edgesClassStyle = EdgesClassStyleEnum.inExamineEdgesColor;
                }
                //当前节点样式为同意样式
                var flowModel = FlowCore.SetCurrentNodeClass(flowData, flowApplyExamineInput.ExamineNodeId, nodeClassStyle);
                //设置当前节点和上个节点的连线样式
                flowModel = FlowCore.SetEdgesAnimated(flowModel, previousNodelModel.id, flowApplyExamineInput.ExamineNodeId, true, edgesClassStyle);
                //设置当前节点和下个节点的连线样式
                flowModel = FlowCore.SetEdgesAnimated(flowModel, flowApplyExamineInput.ExamineNodeId, model.CurrentNodeId, true, EdgesClassStyleEnum.inExamineEdgesColor);
                //设置下一个节点样式为待审核样式
                model.FlowContent = JsonHelper.SerializeObjToJson(FlowCore.SetCurrentNodeClass(flowModel, model.CurrentNodeId, NodeClassStyleEnum.inExamineBackColor));

            }
            //不同意，直接结束
            else if (flowApplyExamineInput.ExamineState == (int)FlowNodeStateEnum.AuditRefuse)
            {
                if (!currentNodeReviewerIdList.Contains(loginResult.UserId.ToString()))
                    return ExceptionHelper.CustomException("操作人员不是当前节点审批人员！");
                //设置当前节点和上个节点的连线样式
                var flowModel = FlowCore.SetEdgesAnimated(flowData, previousNodelModel.id, flowApplyExamineInput.ExamineNodeId, true, EdgesClassStyleEnum.disagreeEdgesColor);
                //设置当前节点样式
                model.FlowContent = JsonHelper.SerializeObjToJson(FlowCore.SetCurrentNodeClass(flowModel, flowApplyExamineInput.ExamineNodeId, NodeClassStyleEnum.disagreeBackColor));
                model.CurrentNodeState = (int)FlowNodeStateEnum.AuditRefuse;
                model.FlowApplyState = (int)FlowApplyStateEnum.AuditRefuse;

                model.CurrentNodeId = string.Empty;
                model.CurrentNodeUpdateTime = DateTime.Now;
                model.CurrentNodeName = string.Empty;
                model.CurrentNodeReviewerId = string.Empty;
                model.CurrentNodeReviewerName = string.Empty;
                model.NextNodeId = string.Empty;
                model.NextNodeName = string.Empty;
                model.NextNodeReviewerId = string.Empty;
                model.NextNodeReviewerName = string.Empty;
                currentNodeState = (int)FlowNodeStateEnum.AuditRefuse;
            }
            //驳回可以选择到驳回步骤
            else if (flowApplyExamineInput.ExamineState == (int)FlowNodeStateEnum.AuditDismissal)
            {
                if (!currentNodeReviewerIdList.Contains(loginResult.UserId.ToString()))
                    return ExceptionHelper.CustomException("操作人员不是当前节点审批人员！");
                //验证是否为空
                if (string.IsNullOrEmpty(flowApplyExamineInput.RejectNodeId))
                    return ExceptionHelper.CustomException("驳回节点不能为空，审核失败！");

                //获取两节点间的节点数据
                rejectNodeIdList.Add(flowApplyExamineInput.ExamineNodeId);
                var nodeList = FlowCore.GetBetweenNodeMsg(flowData, flowApplyExamineInput.RejectNodeId, flowApplyExamineInput.ExamineNodeId, new List<NodeModel>(), model.FormData);
                foreach (var item in nodeList)
                {
                    rejectNodeIdList.Add(item.id);
                }

                //设置下一个当前节点信息
                var currentFlowModel = FlowCore.GetCurrentNodeData(flowData, flowApplyExamineInput.RejectNodeId);

                //设置节点数据
                SetNodeData(flowApplyExamineInput.RejectNodeId, flowData, model, false, loginResult, true);

                //如果驳回节点为开始节点，那么流程申请改为未发布,并且设置开始节点后面那个节点为当前节点
                if (currentFlowModel.type == FlowNodeTypeEnum.input.ToString())
                    model.IsPublish = false;
                else
                    rejectNodeIdList.Add(flowApplyExamineInput.RejectNodeId);

                //当前驳回节点样式为待审核样式
                var flowModel = FlowCore.SetCurrentNodeClass(flowData, flowApplyExamineInput.RejectNodeId, NodeClassStyleEnum.inExamineBackColor);

                //设置当前节点和上个节点的连线样式
                flowModel = FlowCore.SetEdgesAnimated(flowModel, previousNodelModel.id, flowApplyExamineInput.ExamineNodeId, true, EdgesClassStyleEnum.rejectEdgesColor);

                //批量设置节点样式
                model.FlowContent = JsonHelper.SerializeObjToJson(FlowCore.BatchSetNodeClass(flowModel, rejectNodeIdList, NodeClassStyleEnum.rejectBackColor));
                model.CurrentNodeState = (int)FlowNodeStateEnum.AuditDismissal;
                model.FlowApplyState = (int)FlowApplyStateEnum.AuditDismissal;
                currentNodeState = (int)FlowNodeStateEnum.AuditDismissal;
            }
            //归档
            else if (flowApplyExamineInput.ExamineState == (int)FlowNodeStateEnum.Filing)
            {
                if (model.CreateUserKey != loginResult.UserId.ToString())
                    return ExceptionHelper.CustomException("你不是该申请的创建人员，不能归档！");
                if (model.FlowApplyState != (int)FlowApplyStateEnum.AuditPass)
                    return ExceptionHelper.CustomException("只有审核完成的流程才能归档！");

                model.FlowApplyState = (int)FlowApplyStateEnum.Filing;

                model.CurrentNodeId = string.Empty;
                model.CurrentNodeUpdateTime = DateTime.Now;
                model.CurrentNodeName = string.Empty;
                model.CurrentNodeReviewerId = string.Empty;
                model.CurrentNodeReviewerName = string.Empty;
                model.NextNodeId = string.Empty;
                model.NextNodeName = string.Empty;
                model.NextNodeReviewerId = string.Empty;
                model.NextNodeReviewerName = string.Empty;
                model.CurrentNodeState = (int)FlowNodeStateEnum.Filing;
                //设置当前节点和上个节点的连线样式
                var flowModel = FlowCore.SetEdgesAnimated(flowData, previousNodelModel.id, flowApplyExamineInput.ExamineNodeId, true, EdgesClassStyleEnum.agreeEdgesColor);
                //设置当前节点样式
                model.FlowContent = JsonHelper.SerializeObjToJson(FlowCore.SetCurrentNodeClass(flowModel, flowApplyExamineInput.ExamineNodeId, NodeClassStyleEnum.agreeBackColor));
                currentNodeState = (int)FlowNodeStateEnum.Filing;
            }

            //组织审核记录数据
            FlowApplyRecord FlowApplyRecord = new()
            {
                FlowApplyRecordId = Guid.NewGuid().ToString(),
                FlowApplyId = flowApplyExamineInput.FlowApplyId,
                NodeId = flowApplyExamineInput.ExamineNodeId,
                RejectNodeIds = string.Join(',', rejectNodeIdList),
                NodeName = examineNodeModel.data.label,
                NodeType = examineNodeModel.type,
                NodeReviewerId = loginResult.UserId.ToString(),
                NodeReviewerName = loginResult.UserName,
                NodeExamineState = currentNodeState,
                CreateTime = DateTime.Now,
                CreateUserKey = loginResult.UserId.ToString(),
                ExamineRemark = flowApplyExamineInput.ExamineRemark,
            };

            //组织流程信息为已处理状态
            FlowMessage flowMessage = new()
            {
                IsHandled = true,
                HandledTime = DateTime.Now,
                HandledType = (int)HandledTypeEnum.ManualApproval,
                HandledState = currentNodeState,
                MessageRecipient = loginResult.UserId,
                FlowApplyId = flowApplyExamineInput.FlowApplyId,
                NodeId = flowApplyExamineInput.ExamineNodeId,
            };
            var unHandledMessageList = _flowMessageRepository.GetUnHandledFlowMessage(flowMessage);

            //如果当前节点为审核通过，那么需要把该流程推送给抄送人
            List<FlowMessage> carbonCopyList = new List<FlowMessage>();
            if (currentNodeState == (int)FlowNodeStateEnum.AuditPass)
            {
                //获取当前节点信息
                var currentFlowModel = FlowCore.GetCurrentNodeData(flowData, flowApplyExamineInput.ExamineNodeId);
                foreach (var carbonCopyUser in currentFlowModel.data.carbonCopyUser)
                {
                    FlowMessage carbonCopyMsg = new()
                    {
                        MessageId = Guid.NewGuid().ToString(),
                        MessageTitle = model.ApplyTitle,
                        NodeName = currentFlowModel.data.label,
                        NodeId = currentFlowModel.data.nodeId,
                        MessageRecipient = carbonCopyUser,
                        MessageContent = "该流程消息为，推送给抄送人",
                        FlowApplyId = flowApplyExamineInput.FlowApplyId,
                        MessageType = (int)MessageTypeEnum.CarbonCopy,
                        MessageState = (int)MessageStateEnum.Normal,
                        IsBrowse = false,
                        BrowseTime = null,
                        IsHandled = true,
                        HandledTime = DateTime.Now,
                        HandledType = (int)ExpireActionEnum.Approve,
                        HandledState = (int)FlowNodeStateEnum.AuditPass,
                        MessageSender = loginResult.UserId,
                        CreateTime = DateTime.Now,
                        CreateUserKey = loginResult.UserId,
                    };
                    carbonCopyList.Add(carbonCopyMsg);
                }
            }

            //写入数据库
            TransactionHelper.ExecuteTransaction(() =>
            {
                _flowApplyRepository.Update(model, BaseSqlRepository.flowApply_updateSql);

                _flowApplyRecordRepository.Insert(FlowApplyRecord, BaseSqlRepository.flowApplyRecord_insertSql);

                //如果有未处理的消息，修改成已处理状态
                if (unHandledMessageList.Count > 0)
                    _flowMessageRepository.UpdateFlowMessage(flowMessage);

                //把流程推送给抄送人
                if (carbonCopyList.Count > 0)
                    _flowMessageRepository.BulkInsert(carbonCopyList);
            });

            return receiveStatus;
        }

        /// <summary>
        /// 设置节点数据
        /// </summary>
        /// <param name="currentNodeId">当前节点id</param>
        /// <param name="flowData">流程数据</param>
        /// <param name="model">流程申请数据</param>
        /// <param name="isAudt">是否开始审核</param>
        /// <param name="loginResult">登录人员</param>
        /// <param name="isReject">是否驳回</param>
        /// <returns></returns>
        private int SetNodeData(string currentNodeId, FlowModel flowData, FlowApply model, bool isAudt, LoginOutPut loginResult, bool isReject = false)
        {
            //当前节点审核状态
            var currentNodeState = (int)FlowNodeStateEnum.InExamine;
            //获取当前节点信息
            var currentFlowModel = FlowCore.GetCurrentNodeData(flowData, currentNodeId);
            //获取下个节点信息
            var nextFlowModel = FlowCore.GetNextFlowNodeMsg(flowData, currentNodeId, model.FormData);

            //当前节点审批信息
            var nodeModel = SetNodeAuditMsg(model, currentFlowModel, isAudt, loginResult, isReject);
            var userList = MemoryCacheHelper.GetCachedDataByKey<List<SysUser>>(ConstHelper.UserCacheKey);
            if (userList.success == false)
                ExceptionHelper.ThrowBusinessException("用户缓存不存在或已过期,请重置缓存");

            //当前节点审批结束
            if (nodeModel.NodeState == (int)FlowNodeStateEnum.AuditPass)
            {
                currentNodeState = nodeModel.NodeState;
                //下个节点审批信息
                var nextNodeModel = SetNodeAuditMsg(model, nextFlowModel, false, loginResult, isReject);
                //设置当前/下个审批信息
                if (nextFlowModel.type != FlowNodeTypeEnum.output.ToString())
                {
                    SetCurrentNodeData(model, nextNodeModel);
                    //获取下个审批节点信息
                    var nextFlowModel_next = FlowCore.GetNextFlowNodeMsg(flowData, nextNodeModel.NodeId, model.FormData);
                    //设置审批下个节点审批信息
                    var nextNodeModel_next = SetNodeAuditMsg(model, nextFlowModel_next, false, loginResult, isReject);
                    SetNextNodeData(model, nextNodeModel_next);
                }
                else if (nextFlowModel.type == FlowNodeTypeEnum.output.ToString())
                {
                    SetCurrentNodeData(model, nextNodeModel);
                    model.CurrentNodeReviewerId = model.CreateUserKey;
                    var userName = userList?.data?.Find(f => f.UserId == model.CreateUserKey)?.UserName ?? string.Empty;
                    model.CurrentNodeReviewerName = userName;
                    SetOutputNodeData(model);
                }
            }

            //当前节点没有审核结束
            else
            {
                SetCurrentNodeData(model, nodeModel);
                //下个节点审批信息
                var nextNodeModel = SetNodeAuditMsg(model, nextFlowModel, isAudt, loginResult, isReject);
                SetNextNodeData(model, nextNodeModel);

                //如果当前节点为审核完成，并且是会签节点，那么设置下一个节点审批信息为当前节点
                //if (currentFlowModel.type == FlowNodeTypeEnum.countersign.ToString())
                //{
                //    var reviewerId = GetNextId(nextFlowModel.data.reviewerIds, nodeModel.NodeReviewerId);
                //    var reviewerName = userList?.data.Find(f => f.UserId.ToString() == reviewerId)?.UserName ?? string.Empty;
                //    var nextNodeModel_next = new NodeAuditModel
                //    {
                //        NodeId = nodeModel.NodeId,
                //        NodeName = nodeModel.NodeName,
                //        NodeReviewerId = reviewerId,
                //        NodeReviewerName = reviewerName,
                //    };
                //    SetNextNodeData(model, nextNodeModel_next);
                //}
                //else
                //{
                //    //下个节点审批信息
                //    var nextNodeModel = SetNodeAuditMsg(model, nextFlowModel, isAudt, loginResult);
                //    SetNextNodeData(model, nextNodeModel);
                //}
            }
            return currentNodeState;
        }

        /// <summary>
        /// 获取申请当前节点前的所有节点数据
        /// </summary>
        /// <param name="flowApplyId">流程申请id</param>
        /// <returns></returns>
        public ReceiveStatus<List<SelectOutPut>> GetExamineNodeSelectData(string flowApplyId)
        {
            ReceiveStatus<List<SelectOutPut>> receiveStatus = new();
            //验证该申请是否存在
            var model = _flowApplyRepository.GetByKey(flowApplyId, BaseSqlRepository.flowApply_selectByKeySql);
            if (model == null)
                return ExceptionHelper<List<SelectOutPut>>.CustomExceptionData("该申请不存在！");
            //验证是否有审核记录
            var flowApplyRecordList = _flowApplyRecordRepository.GetFlowApplyRecordByFlowApplyId(flowApplyId);
            if (flowApplyRecordList == null || flowApplyRecordList.Count == 0)
                return ExceptionHelper<List<SelectOutPut>>.CustomExceptionData("该申请不存在,不存在审核节点！");

            //验证是否是开始节点和归档节点
            var flowData = JsonHelper.JsonStrToEntity<FlowModel>(model.FlowContent);
            var startNode = FlowCore.GetStartNode(flowData);
            if (startNode == null)
                return ExceptionHelper<List<SelectOutPut>>.CustomExceptionData("未找到流程开始节点！");
            var nodeList = FlowCore.GetBetweenNodeMsg(flowData, startNode.id, model.CurrentNodeId, new List<NodeModel>(), model.FormData).Where(f => f.type != FlowNodeTypeEnum.input.ToString() || f.id != model.CurrentNodeId).ToList();
            var list = nodeList.GroupBy(g => new { g.id, g.data.label }).Select(s => new SelectOutPut
            {
                value = s.Key.id,
                label = s.Key.label
            }).ToList();
            //list.Add(new SelectOutPut
            //{
            //    value = startNode.id,
            //    label = startNode.data.label
            //});
            receiveStatus.data = list;
            return receiveStatus;
        }

        /// <summary>
        /// 获取已审核节点数据
        /// </summary>
        /// <param name="flowApplyId"></param>
        /// <returns></returns>
        public ReceiveStatus<List<FlowApplyRecord>> GetExamineNodeData(string flowApplyId)
        {
            ReceiveStatus<List<FlowApplyRecord>> receiveStatus = new();
            //验证该申请是否存在
            var model = _flowApplyRepository.GetByKey(flowApplyId, BaseSqlRepository.flowApply_selectByKeySql);
            if (model == null)
                return ExceptionHelper<List<FlowApplyRecord>>.CustomExceptionData("该申请不存在！");
            //验证是否有审核记录
            var flowApplyRecordList = _flowApplyRecordRepository.GetFlowApplyRecordByFlowApplyId(flowApplyId);
            if (flowApplyRecordList == null || flowApplyRecordList.Count == 0)
                return ExceptionHelper<List<FlowApplyRecord>>.CustomExceptionData("该申请不存在,不存在审核节点！");
            foreach (var item in flowApplyRecordList)
            {
                item.NodeExamineStateName = EnumHelper.GetDescription((FlowNodeStateEnum)item.NodeExamineState);
            }
            receiveStatus.data = flowApplyRecordList;
            return receiveStatus;
        }

        /// <summary>
        /// 设置节点审核信息
        /// </summary>
        /// <param name="FlowApply">流程申请模型</param>
        /// <param name="currentFlowModel">当前节点模型</param>
        /// <param name="isAudt">是否开始审核</param>
        /// <param name="loginResult">登录人</param>
        /// <param name="isReject">是否驳回</param>
        public NodeAuditModel SetNodeAuditMsg(FlowApply FlowApply, NodeModel currentFlowModel, bool isAudt, LoginOutPut loginResult, bool isReject = false)
        {
            NodeAuditModel nodeAuditModel = new();
            nodeAuditModel.NodeId = currentFlowModel.id;
            nodeAuditModel.NodeName = currentFlowModel.data.label;
            nodeAuditModel.NodeState = (int)FlowNodeStateEnum.InExamine;
            var userData = MemoryCacheHelper.GetCachedDataByKey<List<SysUser>>(ConstHelper.UserCacheKey);
            if (userData.success == false)
                ExceptionHelper.ThrowBusinessException("用户缓存不存在或已过期,请重置缓存");
            if (currentFlowModel.type == FlowNodeTypeEnum.countersign.ToString())
            {
                nodeAuditModel.NodeReviewerName = string.Empty;
                var userList = userData?.data?.Where(w => currentFlowModel.data.reviewerIds.Contains(w.UserId ?? string.Empty)).ToList() ?? new List<SysUser>();

                //设置当前节点所有审核人信息
                nodeAuditModel.NodeReviewerId = string.Join(",", currentFlowModel.data.reviewerIds);
                foreach (var item in currentFlowModel.data.reviewerIds)
                {
                    var userModel = userList.Where(f => f.UserId.ToString() == item).FirstOrDefault();
                    nodeAuditModel.NodeReviewerName += userModel?.UserName + ",";
                }
                nodeAuditModel.NodeReviewerName = nodeAuditModel.NodeReviewerName.Trim(',');

                //如果是所有人都审批+按顺序审批
                var nodeExtendModel = currentFlowModel.data;
                if (nodeExtendModel.countersignWay == NodeCountersignWayEnum.AllReviewerExamine && nodeExtendModel.countersignOrder == NodeCountersignOrderEnum.OrderAsc)
                {
                    var flowApplyRecordModel = _flowApplyRecordRepository.GetFlowApplyRecordByNodeId(currentFlowModel.id, FlowApply.FlowApplyId).FirstOrDefault();
                    var rejectNodeRecordModel = _flowApplyRecordRepository.GetFlowApplyRecordByRejectNodeIds(currentFlowModel.id, FlowApply.FlowApplyId).FirstOrDefault();
                    if (flowApplyRecordModel?.CreateTime < rejectNodeRecordModel?.CreateTime)
                        flowApplyRecordModel.NodeExamineState = (int)FlowNodeStateEnum.AuditDismissal;
                    if (isReject)
                        flowApplyRecordModel.NodeExamineState = (int)FlowNodeStateEnum.AuditDismissal;
                    //没有审批记录或者驳回，取第二个审批人，作为当前节点审批人
                    if (flowApplyRecordModel == null || flowApplyRecordModel?.NodeExamineState == (int)FlowNodeStateEnum.AuditDismissal)
                    {
                        if (isAudt)
                        {
                            var userId = currentFlowModel.data.reviewerIds.FirstOrDefault();
                            nodeAuditModel.NodeReviewerId = GetNextId(currentFlowModel.data.reviewerIds, userId);
                            nodeAuditModel.NodeReviewerName = userList.Where(f => f.UserId.ToString() == nodeAuditModel.NodeReviewerId).FirstOrDefault()?.UserName ?? string.Empty;
                        }
                        else
                        {
                            nodeAuditModel.NodeReviewerId = currentFlowModel.data.reviewerIds.FirstOrDefault() ?? string.Empty;
                            nodeAuditModel.NodeReviewerName = userList.Where(f => f.UserId.ToString() == nodeAuditModel.NodeReviewerId).FirstOrDefault()?.UserName ?? string.Empty;
                        }
                    }

                    //如果有审批记录，并且节点审核还未结束，那么取上一个人审批人之后的审批人，作为当前节点审批人
                    else if (flowApplyRecordModel != null && flowApplyRecordModel.NodeExamineState != (int)FlowNodeStateEnum.AuditPass)
                    {
                        var reviewerId = GetNextId(currentFlowModel.data.reviewerIds, flowApplyRecordModel.NodeReviewerId);
                        nodeAuditModel.NodeReviewerId = GetNextId(currentFlowModel.data.reviewerIds, reviewerId);
                        nodeAuditModel.NodeReviewerName = userList.Where(f => f.UserId.ToString() == nodeAuditModel.NodeReviewerId).FirstOrDefault()?.UserName ?? string.Empty;
                    }

                    //是否最后一个审批人，设置节点审核状态
                    // var nextReviewerId = GetNextId(currentFlowModel.data.reviewerIds, nodeAuditModel.NodeReviewerId);
                    if (string.IsNullOrWhiteSpace(nodeAuditModel.NodeReviewerId))
                        nodeAuditModel.NodeState = (int)FlowNodeStateEnum.AuditPass;
                }

                //如果是所有人都审批+不按顺序审批
                if (nodeExtendModel.countersignWay == NodeCountersignWayEnum.AllReviewerExamine && nodeExtendModel.countersignOrder == NodeCountersignOrderEnum.NoOrder)
                {
                    if (isAudt)
                    {
                        //待审核人信息
                        var unAuditUserList = userData?.data?.Where(w => FlowApply.CurrentNodeReviewerId.Contains(w.UserId ?? string.Empty)).ToList() ?? new List<SysUser>();
                        //下次审核人id
                        var nextUnAuditUserList = unAuditUserList.Where(f => f.UserId != loginResult.UserId).ToList();
                        if (nextUnAuditUserList.Count > 0)
                        {
                            //设置当前审核人为当前节点所有人员
                            nodeAuditModel.NodeReviewerName = string.Join(',', nextUnAuditUserList.Select(f => f.UserName).ToList());
                            nodeAuditModel.NodeReviewerId = string.Join(',', nextUnAuditUserList.Select(f => f.UserId).ToList());
                        }
                        //是否最后一个审批人，设置节点审核状态
                        else
                            nodeAuditModel.NodeState = (int)FlowNodeStateEnum.AuditPass;
                    }
                    else
                    {
                        //设置当前审核人为当前节点所有人员
                        nodeAuditModel.NodeReviewerId = string.Join(",", currentFlowModel.data.reviewerIds);
                        nodeAuditModel.NodeReviewerName = nodeAuditModel.NodeReviewerName.Trim(',');
                    }

                }

                //如果是任意一人审批
                if (nodeExtendModel.countersignWay == NodeCountersignWayEnum.EitherReviewerExamine)
                {
                    //设置当前审核人为当前节点所有人员
                    nodeAuditModel.NodeReviewerId = string.Join(",", currentFlowModel.data.reviewerIds);
                    nodeAuditModel.NodeReviewerName = nodeAuditModel.NodeReviewerName.Trim(',');
                    nodeAuditModel.NodeState = isAudt ? (int)FlowNodeStateEnum.AuditPass : (int)FlowNodeStateEnum.InExamine;
                }
            }
            else if (currentFlowModel.type != FlowNodeTypeEnum.output.ToString())
            {
                var currentUserModel = userData?.data.Find(w => currentFlowModel.data.reviewerIds.Contains(w.UserId ?? string.Empty));
                //var currentUserModel = _sysUserRepository.GetByKey(currentFlowModel.data.reviewerId, BaseSqlRepository.sysUser_selectByKeySql);
                nodeAuditModel.NodeReviewerId = currentFlowModel.data.reviewerIds[0];
                nodeAuditModel.NodeReviewerName = currentUserModel?.UserName ?? string.Empty;
                nodeAuditModel.NodeState = isAudt ? (int)FlowNodeStateEnum.AuditPass : (int)FlowNodeStateEnum.InExamine;
            }

            //归档节点
            //else if (currentFlowModel.type == FlowNodeTypeEnum.output.ToString())
            //{
            //    FlowApply.NextNodeId = string.Empty;
            //    FlowApply.NextNodeName = string.Empty;
            //    FlowApply.NextNodeReviewerId = string.Empty;
            //    FlowApply.NextNodeReviewerName = string.Empty;
            //    FlowApply.NextNodeReviewerIds = string.Empty;
            //    FlowApply.NextNodeReviewerNames = string.Empty;
            //    FlowApply.FlowApplyState = (int)FlowApplyStateEnum.AuditPass;
            //}

            return nodeAuditModel;
        }


        /// <summary>
        /// 设置当前节点信息
        /// </summary>
        /// <param name="model"></param>
        /// <param name="nodeModel"></param>
        private void SetCurrentNodeData(FlowApply model, NodeAuditModel nodeModel)
        {
            model.CurrentNodeId = nodeModel?.NodeId ?? string.Empty;
            model.CurrentNodeName = nodeModel?.NodeName ?? string.Empty;
            model.CurrentNodeReviewerId = nodeModel?.NodeReviewerId ?? string.Empty;
            model.CurrentNodeReviewerName = nodeModel?.NodeReviewerName ?? string.Empty;
            model.CurrentNodeState = (int)FlowNodeStateEnum.InExamine;
            model.CurrentNodeUpdateTime = DateTime.Now;
        }

        /// <summary>
        /// 设置下个节点信息
        /// </summary>
        /// <param name="model"></param>
        /// <param name="nodeModel"></param>
        private void SetNextNodeData(FlowApply model, NodeAuditModel nodeModel)
        {
            model.NextNodeId = nodeModel?.NodeId ?? string.Empty;
            model.NextNodeName = nodeModel?.NodeName ?? string.Empty;
            model.NextNodeReviewerId = nodeModel?.NodeReviewerId ?? string.Empty;
            model.NextNodeReviewerName = nodeModel?.NodeReviewerName ?? string.Empty;
        }

        /// <summary>
        /// 设置归档节点信息
        /// </summary>
        /// <param name="model"></param>
        private void SetOutputNodeData(FlowApply model)
        {
            model.NextNodeId = string.Empty;
            model.NextNodeName = string.Empty;
            model.NextNodeReviewerId = string.Empty;
            model.NextNodeReviewerName = string.Empty;
            model.FlowApplyState = (int)FlowApplyStateEnum.AuditPass;
            model.CurrentNodeState = (int)FlowNodeStateEnum.AuditPass;
        }

        /// <summary>
        /// 获取下一个id
        /// </summary>
        /// <param name="list">集合</param>
        /// <param name="currentUserId">当前id</param>
        /// <returns></returns>
        public string GetNextId(List<string> list, string currentUserId)
        {
            // 查找当前ID在列表中的位置
            int currentIndex = list.FindIndex(item => item == currentUserId);

            // 检查是否找到了当前ID，并且还有下一条数据
            if (currentIndex != -1 && currentIndex < list.Count - 1)
            {
                // 获取下一条数据
                string nextItem = list[currentIndex + 1];
                return nextItem;
            }
            else
            {
                return string.Empty;
            }
        }

        #endregion
    }
}
